/**
 * <AiRmob-Framework; A simple augmented reality framework for android >
    Copyright (C) <2012>  <AiRmob Team>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package rendercomponents;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public abstract class Model3D extends Object {

	// ////////////////////////////////////////////////////////
	// /Variables
	// ////////////////////////////////////////////////////////

	VectorMethods vectorMethods = new VectorMethods();

	// Constants
	protected static final int FLOAT_SIZE_BYTES = 4;
	protected static final int SHORT_SIZE_BYTES = 2;
	protected static final int VERTICES_DATA_STRIDE_FLOAT = 8;

	// Arrays for vertices, indices, normals & texturecoordinates
	protected float vertices[];
	protected short indices[];

	private float materialAmbient[];
	private float materialDiffuse[];
	private float materialSpecular[];
	private float materialExponent;

	protected Texture texture;
	protected Texture bumpMap;
	protected Mesh mesh;

	// All used buffers
	protected ShortBuffer bIndexBuffer;

	protected int iBuffer;
	protected int numIndices;

	boolean changed = false;
	boolean normalsSet = false;
	boolean textureCoordsSet = false;

	boolean textureSet = false;
	boolean bumpMapSet = false;

	private boolean isTransparent = false;

	// ////////////////////////////////////////////////////////
	// /Functions for textures (& bumpMap)
	// ////////////////////////////////////////////////////////

	public void useTexture(Texture texture) {
		this.texture = texture;
		this.textureSet = true;
	}

	public void useBumpMap(Texture bumpMap) {
		this.bumpMap = bumpMap;
		this.bumpMapSet = true;
	}

	// ////////////////////////////////////////////////////////
	// /Constructor
	// ////////////////////////////////////////////////////////

	public Model3D() {
		super();
		this.mesh = new Mesh();
		this.type = 1;
	}

	// ////////////////////////////////////////////////////////
	// /Getters and setters (not all are trivial)
	// ////////////////////////////////////////////////////////

	public void setTexture(Texture texture) {
		this.texture = texture;
		this.textureSet = true;
	}

	public Texture getTexture() {
		return this.texture;
	}

	public float[] getVertices() {
		return vertices;
	}

	public void setVertices(float[] vertices) {
		this.vertices = vertices;
	}

	public int getNumVertices() {
		return this.vertices.length;
	}

	public short[] getIndices() {
		return indices;
	}

	public void setIndices(short[] indices) {
		this.indices = indices;
	}

	public float[] getMaterialAmbient() {
		return materialAmbient;
	}

	public void setMaterialAmbient(float[] materialAmbient) {
		this.materialAmbient = materialAmbient;
	}

	public float[] getMaterialDiffuse() {
		return materialDiffuse;
	}

	public void setMaterialDiffuse(float[] materialDiffuse) {
		this.materialDiffuse = materialDiffuse;
	}

	public float[] getMaterialSpecular() {
		return materialSpecular;
	}

	public void setMaterialSpecular(float[] materialSpecular) {
		this.materialSpecular = materialSpecular;
	}

	public float getMaterialExponent() {
		return materialExponent;
	}

	public void setMaterialExponent(float materialExponent) {
		this.materialExponent = materialExponent;
	}

	public FloatBuffer getbVertexBuffer() {
		return mesh.bVertexBuffer;
	}

	public void setbVertexBuffer(FloatBuffer bVertexBuffer) {
		mesh.bVertexBuffer = bVertexBuffer;
	}

	public void setbVertexBuffer(float[] vertexArray) {
		mesh.bVertexBuffer = ByteBuffer
				.allocateDirect(vertexArray.length * FLOAT_SIZE_BYTES)
				.order(ByteOrder.nativeOrder()).asFloatBuffer();
		mesh.bVertexBuffer.put(vertexArray);
		mesh.bVertexBuffer.position(0);
	}

	public ShortBuffer getbIndexBuffer() {
		return bIndexBuffer;
	}

	public void setbIndexBuffer(ShortBuffer bIndexBuffer) {
		this.bIndexBuffer = bIndexBuffer;
	}

	public void setbIndexBuffer(short[] indexArray) {
		bIndexBuffer = ByteBuffer
				.allocateDirect(indexArray.length * SHORT_SIZE_BYTES)
				.order(ByteOrder.nativeOrder()).asShortBuffer();
		bIndexBuffer.put(indexArray);
		bIndexBuffer.position(0);
	}

	public Texture getBumpMap() {
		return bumpMap;
	}

	public void setBumpMap(Texture bumpMap) {
		this.bumpMap = bumpMap;
		this.bumpMapSet = true;
	}

	public boolean isTextureCoordsSet() {
		return textureCoordsSet;
	}

	public void setTextureCoordsSet(boolean textureCoordsSet) {
		this.textureCoordsSet = textureCoordsSet;
	}

	public boolean isTextureSet() {
		return textureSet;
	}

	public void setTextureSet(boolean textureSet) {
		this.textureSet = textureSet;
	}

	public boolean isBumpMapSet() {
		return bumpMapSet;
	}

	public void setBumpMapSet(boolean bumpMapSet) {
		this.bumpMapSet = bumpMapSet;
	}

	public void setTransparent(boolean isTransparent) {
		this.isTransparent = isTransparent;
	}

	public boolean isTransparent() {
		return isTransparent;
	}

}
